#include "Buffer.h"
#include <errno.h>
#include <sys/uio.h>
#include <unistd.h>
/*readv  writev 对于管理缓冲区读写数据非常好 */
/*
Buffer缓冲区是有大小的  但是从fd读数据时 不知道tcp数据最终大小
*/
ssize_t Buffer::readFd(int fd, int* savedErrno) {
    char extrabuf[65536]; //栈上空间
    struct iovec vec[2];
    const size_t writeable = writableBytes(); //这是Buffer缓冲区剩余可写空间大小
    vec[0].iov_base = begin() + writerIndex_;
    vec[0].iov_len = writeable;
    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof extrabuf;

    const int iovcnt = (writeable < sizeof extrabuf) ? 2 : 1; // 如果buffer_可写空间比64k还大，就不需要extrabuf来充当临时缓存了
    const ssize_t n = ::readv(fd, vec, iovcnt);
    if (n < 0) {
        *savedErrno = errno;
    }
    else if (n <= writeable) //buffer本身的可写空间可以存储下来了
    {
        writerIndex_ += n;
    }
    else // extrabuf中也有数据待读
    {
        writerIndex_ = buffer_.size();
        append(extrabuf, n - writeable); // append会根据需要读入数据扩容
    }

    return n;
}

ssize_t Buffer::writeFd(int fd, int *saveErrno) {
    ssize_t n = ::write(fd, peek(), readableBytes());
    if (n < 0) {
        *saveErrno = errno;

    }

    return n;
}